package com.symaster.common.geom.entity;

import com.symaster.common.geom.util.ArithUtil;
import com.symaster.common.geom.util.PointUtil;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
import java.util.UUID;

/**
 * 点实体
 *
 * @author yinmiao
 * @date 2021-08-10 08:30
 */
public class Point implements Serializable {

    private final String uid;
    public double x, y;
    private static final double ACCURACY = 0.000000001;

    @Deprecated
    public Point() {
        this(0,0);
    }

    public Point(double x, double y) {
        BigDecimal bigDecimalx = new BigDecimal(x);
        this.x = bigDecimalx.setScale(6, RoundingMode.HALF_UP).doubleValue();
        BigDecimal bigDecimaly = new BigDecimal(y);
        this.y = bigDecimaly.setScale(6, RoundingMode.HALF_UP).doubleValue();
        this.uid = UUID.randomUUID().toString();
    }

    public java.awt.Point toAwtPoint() {
        return new java.awt.Point(getXasInt(), getYasInt());
    }

    public Point sum(Point p2) {
        return new Point(x + p2.x, y + p2.y);
    }

    public Point multiplier(double m) {
        return new Point(ArithUtil.mul(x, m), ArithUtil.mul(y, m));
    }

    public void rotateTransform(double angle, Point center) {
        Point point = PointUtil.rotateTransform(this, center, angle);
        x = point.x;
        y = point.y;
    }

    public int getXasInt() {
        return (int) x;
    }

    public int getYasInt() {
        return (int) y;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        BigDecimal bigDecimalx = new BigDecimal(x);
        this.x = bigDecimalx.setScale(6, RoundingMode.HALF_UP).doubleValue();
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        BigDecimal bigDecimaly = new BigDecimal(y);
        this.y = bigDecimaly.setScale(6, RoundingMode.HALF_UP).doubleValue();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return Double.compare(Math.abs(point.x - x), 1e-5) < ACCURACY && Double.compare(Math.abs(point.y - y), 1e-5) < ACCURACY;
    }

    @Override
    public int hashCode() {
        return Objects.hash(uid);
    }

    @Override
    public String toString() {
        return "Point{" +
                "x=" + Double.parseDouble(String.format("%.4f", x)) +
                ", y=" + Double.parseDouble(String.format("%.4f", y)) +
                '}';
    }
}
